﻿using FR.CodeVisualizer.Visualizers;
using Microsoft.VisualStudio.DebuggerVisualizers;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.EntityClient;
using System.Data.Objects;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace FR.CodeVisualizer.ObjectSource
{
    public class EFVisualizerObjectSource : VisualizerObjectSource
    {
        public override void GetData(object target, System.IO.Stream outgoingData)
        {
            SQLQueryOptions sqlOptions = null;

            try
            {
                if (target is ObjectQuery)
                {
                    sqlOptions = (target as ObjectQuery).ToSqlString();
                }
                else if (target is ObjectContext)
                {
                    sqlOptions = (target as ObjectContext).ToSqlString();
                }
            }
            catch (Exception ex)
            {
                sqlOptions = new SQLQueryOptions();
                sqlOptions.SetExceptionMessage(ex);
            }

            StreamSerializer.ObjectToStream(outgoingData, sqlOptions);
        }
    }

    public static class ObjectContextExtensionMethods
    {
        public static SQLQueryOptions ToSqlString(this ObjectQuery objectQuery)
        {
            SQLQueryOptions sqlOptions = new SQLQueryOptions();
            sqlOptions.IsQuery = true;
            sqlOptions.SQLCommand = objectQuery.ToTraceString();

            StringBuilder sb = new StringBuilder();
            if (objectQuery.Context != null && objectQuery.Context.Connection != null && objectQuery.Context.Connection is EntityConnection)
                sqlOptions.ConnectionString = (objectQuery.Context.Connection as EntityConnection).StoreConnection.ConnectionString;

            foreach (ObjectParameter parameter in objectQuery.Parameters)
            {
                System.Data.SqlClient.SqlParameter r = new System.Data.SqlClient.SqlParameter(parameter.ParameterType.FullName, parameter.Value);

                sb.AppendLine(string.Format("DECLARE @{0} {1}{2};", parameter.Name, r.SqlDbType, ContextHelper.GetTypeLength(r.SqlDbType)));
                sb.AppendLine(string.Format("SET @{0} = '{1}';", parameter.Name, parameter.Value));
            }

            sb.AppendLine();
            sb.AppendLine(sqlOptions.SQLCommand);

            sqlOptions.SQLCommand = sb.ToString();

            return sqlOptions;
        }

        public static SQLQueryOptions ToSqlString(this ObjectContext objectContext)
        {
            SQLQueryOptions sqlOptions = new SQLQueryOptions();

            sqlOptions.ConnectionString = (objectContext.Connection as EntityConnection).StoreConnection.ConnectionString;
            sqlOptions.SQLCommand = ContextHelper.GetSQLCommands(objectContext);

            return sqlOptions;
        }
    }
}
